package com.CST.service.impl.cb;

import com.CST.dto.cb.DateDTO;
import com.CST.entity.cb.BaseSalary;
import com.CST.entity.cb.BdEnumdetail;
import com.CST.entity.cb.CusDutyfactor;
import com.CST.entity.cb.RuleCompelamortization;
import com.CST.mapper.cst.cb.BaseCostMapper;
import com.CST.mapper.cst.cb.BaseSalaryMapper;
import com.CST.mapper.cst.cb.CusDutyfactorMapper;
import com.CST.mapper.cst.cb.RuleCompelamortizationMapper;
import com.CST.mapper.dataplatform.BdDepartmentMapper;
import com.CST.mapper.dataplatform.BdEnumdetailMapper;
import com.CST.service.cb.IBaseSalaryService;
import com.CST.vo.cb.BdSysUserDeptCodeVO;
import com.CST.vo.cb.ReportBaseSalaryVO;
import com.CST.vo.cb.ReportSalaryDetailVO;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ly
 * @since 2022-04-20
 */
@Service
public class BaseSalaryServiceImpl extends ServiceImpl<BaseSalaryMapper, BaseSalary> implements IBaseSalaryService {

    @Autowired
    private BaseSalaryMapper baseSalaryMapper;

    @Autowired
    private BaseCostMapper baseCostMapper;
     @Autowired
     private CusDutyfactorMapper   cusDutyfactorMapper;
    @Autowired
    private BdDepartmentMapper bdDepartmentMapper;
    @Autowired
    private BdEnumdetailMapper bdEnumdetailMapper;
    @Autowired
    private RuleCompelamortizationMapper ruleCompelamortizationMapper;
    /**
     * 采集人员经费明细
     *
     * @param dateDTO
     */
    @Override
    public void insertBaseSalary(DateDTO dateDTO) {

        List<BaseSalary> baseSalaryList = new ArrayList<>();
        List<BaseSalary> baseSalaries = baseSalaryMapper.listFirstSalaryByDate(dateDTO);
        List<CusDutyfactor> cusDutyfactors = cusDutyfactorMapper.selectDutyFactor(dateDTO);
        List<BdSysUserDeptCodeVO> costDepartment = bdDepartmentMapper.getCostDepartment();
        List<BdEnumdetail> bdEnumdetails = bdEnumdetailMapper.listAllDeptSalaryRelation();
        for (BaseSalary baseSalary : baseSalaries) {
            BdSysUserDeptCodeVO bdSysUserDeptCodeVO = costDepartment.stream().filter(t -> t.getDeptCode().equals(baseSalary.getDeptCode())).findFirst().orElse(null);
            baseSalary.setPDeptCode(bdSysUserDeptCodeVO.getPDeptCode());
            baseSalary.setPDeptName(bdSysUserDeptCodeVO.getPDeptName());
            baseSalary.setDeptTypeId(bdSysUserDeptCodeVO.getDeptTypeId());
            baseSalary.setDeptTypeName(bdSysUserDeptCodeVO.getDeptTypeName());
            List<CusDutyfactor> collect = cusDutyfactors.stream().filter(t -> t.getEmployeecode().equals(baseSalary.getEmpId())).collect(Collectors.toList());
            BdEnumdetail bdEnumdetail = bdEnumdetails.stream().filter(t -> t.getEdExtraFirstCode().equals(baseSalary.getExtraA())).findFirst().orElse(null);

            if (CollectionUtils.isNotEmpty(collect)&& StringUtils.isNotBlank(bdEnumdetail.getEdExtraThirdCode())){
                for (CusDutyfactor cusDutyfactor : collect) {
                    if (cusDutyfactor.getRemark().equals("ZY")){
                        baseSalary.setAmount(baseSalary.getAmount().multiply(new BigDecimal(cusDutyfactor.getRulecode())));
                    }
                    if (cusDutyfactor.getRemark().equals("MZ")){
                        BaseSalary baseSalary1 = new BaseSalary();
                        BeanUtils.copyProperties(baseSalary,baseSalary1);
                        baseSalary1.setAmount(baseSalary.getAmount().multiply(new BigDecimal(cusDutyfactor.getRulecode())));
                        baseSalary1.setDeptCode(bdEnumdetail.getEdExtraThirdCode());
                        baseSalary1.setDeptName(bdEnumdetail.getEdExtraThirdDescription());
                        baseSalaryList.add(baseSalary1);
                    }
                }
            }
        }
        baseSalaryList.addAll(baseSalaries);
    //    baseSalaryList =this.splitBaseSalary(baseSalaryList,dateDTO);
        Integer year = dateDTO.getYear();
        int total1 = baseSalaryList.size();//为防止插入字符超过最大数,分批插入
        int fromIndex1 = 0;
        List<BaseSalary> insertList1 = new ArrayList<>();
        for (int i = 0; i < baseSalaryList.size(); i++) {
            BaseSalary item = baseSalaryList.get(i);
            fromIndex1++;
            insertList1.add(item);
            if (fromIndex1 % 20 == 0 && fromIndex1 <= total1) {
                baseSalaryMapper.insertBaseSalary(insertList1, year);
                insertList1 = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList1)) {
            baseSalaryMapper.insertBaseSalary(insertList1, year);
        }

        List<BaseSalary> baseSalaries1 = this.splitBaseSalary(baseSalaryList, dateDTO);

        int total2 = baseSalaries1.size();//为防止插入字符超过最大数,分批插入
        int fromIndex2 = 0;
        List<BaseSalary> insertList2 = new ArrayList<>();
        for (int i = 0; i < baseSalaries1.size(); i++) {
            BaseSalary item = baseSalaries1.get(i);
            fromIndex2++;
            insertList2.add(item);
            if (fromIndex2 % 20 == 0 && fromIndex2 <= total2) {
                baseSalaryMapper.insertBaseSalaryDEL(insertList2, year);
                insertList2 = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList2)) {
            baseSalaryMapper.insertBaseSalaryDEL(insertList2, year);
        }
    }





    public  List<BaseSalary>  splitBaseSalary( List<BaseSalary> baseSalaryList, DateDTO dateDTO) {
        List<BaseSalary> baseSalaries = new ArrayList<>();
        List<RuleCompelamortization> compelRule = ruleCompelamortizationMapper.getCompelRule(dateDTO.getYear(),
                dateDTO.getMonth());
        for (BaseSalary baseSalary : baseSalaryList) {
            List<RuleCompelamortization> collect = compelRule.stream().filter(t -> t.getDeptcode().equals(baseSalary.getDeptCode())).collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(collect)){
                for (RuleCompelamortization ruleCompelamortization : collect) {
                    BaseSalary baseSalary1 = new BaseSalary();
                    BeanUtils.copyProperties(baseSalary,baseSalary1);
                    baseSalary1.setDeptCode(ruleCompelamortization.getTodeptcode());
                    baseSalary1.setDeptName(ruleCompelamortization.getTodeptname());
                    baseSalary1.setAmount(baseSalary1.getAmount().multiply(new BigDecimal(ruleCompelamortization.getRulecode())));
                    baseSalary1.setExtraA(null);
                    baseSalaries.add(baseSalary1);
                }

            }else {
                baseSalaries.add(baseSalary);
            }
        }
        return  baseSalaries;
    }

    /**
     * 获取人员经费1级详情
     * 需要传入父级科室
     * 按照账套归类显示
     *
     * @param dateDTO
     * @param pDeptCode
     * @return
     */
    @Override
    public List listSalaryWithAccByPDeptCode(DateDTO dateDTO, String pDeptCode) {
        List<ReportSalaryDetailVO> list = new ArrayList<>();
        List<ReportBaseSalaryVO> reportBaseSalaryVOList = baseSalaryMapper.listSalaryWithAccByPDeptCode(dateDTO, pDeptCode);
        // 获取所有科室
        List<String> deptCodeList = reportBaseSalaryVOList.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        // 获取所有账套
        List<String> accIdList = reportBaseSalaryVOList.stream().map(t -> t.getAccId()).distinct().collect(Collectors.toList());
        for (String deptCode : deptCodeList) {
            ReportSalaryDetailVO reportSalaryDetailVO = new ReportSalaryDetailVO();
            List<ReportBaseSalaryVO> salaryVOList = reportBaseSalaryVOList.stream().filter(t -> deptCode.equals(t.getDeptCode())).collect(Collectors.toList());
            Map<String, BigDecimal> map = new HashMap<>();
            for (String accId : accIdList) {
                map.put(accId, salaryVOList.stream().filter(t -> accId.equals(t.getAccId())).map(t -> t.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
            }
            ReportBaseSalaryVO reportBaseSalaryVO = reportBaseSalaryVOList.stream().filter(t -> deptCode.equals(t.getDeptCode())).findFirst().orElse(null);
            String deptName = reportBaseSalaryVO.getDeptName();
            reportSalaryDetailVO.setDeptCode(deptCode);
            reportSalaryDetailVO.setDeptName(deptName);
            reportSalaryDetailVO.setAccParam(map);
            list.add(reportSalaryDetailVO);
        }
        return list;
    }

    /**
     * 根据父级科室+子科室获取人员经费明细
     * 点击人员经费1级明细的子科室生效
     *
     * @param dateDTO
     * @param pDeptCode
     * @param deptCode
     * @return
     */
    @Override
    public List<BaseSalary> listSalaryByPDeptCodeAndDeptCode(DateDTO dateDTO, String pDeptCode, String deptCode) {
        List<BaseSalary> baseSalaryList = baseSalaryMapper.listSalaryByPDeptCodeAndDeptCode(dateDTO, pDeptCode, deptCode);
        return baseSalaryList;
    }

    /**
     * 人员经费明细
     * 点击人员经费1级明细的账套生效
     *
     * @param dateDTO
     * @param pDeptCode
     * @param deptCode
     * @param accId
     * @return
     */
    @Override
    public List<ReportBaseSalaryVO> listSalaryByDeptAndAccId(DateDTO dateDTO, String pDeptCode, String deptCode, String accId) {
        List<ReportBaseSalaryVO> reportBaseSalaryVOList = baseSalaryMapper.listSalaryByDeptAndAccId(dateDTO, pDeptCode, deptCode, accId);
        return reportBaseSalaryVOList;
    }

    /**
     * 人员经费1级明细
     * 查询薪酬和绩效系统的人员经费总额
     * 需要传入时间和父级科室信息
     *
     * @param dateDTO
     * @param pDeptCode
     * @return
     */
    @Override
    public List<ReportBaseSalaryVO> listSalaryWithExtraByPDeptCode(DateDTO dateDTO, String pDeptCode) {
        List<ReportBaseSalaryVO> result =baseCostMapper.listSalaryWithExtraByPDeptCode(dateDTO, pDeptCode);
//        if(pDeptCode.equals("9999"))
//        {
//            List<ReportBaseSalaryVO> offsetList =baseCostMapper.getOffsetSalary(dateDTO);
//            if(CollectionUtils.isNotEmpty(offsetList))
//            {
//                result.addAll(offsetList);
//            }
//        }
        result = result.stream().filter(t -> t.getSalaryAmount().compareTo(BigDecimal.ZERO) != 0 || t.getPerformanceAmount().compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toList());
        return result;
    }

    @Override
    public List<ReportBaseSalaryVO> listSalaryWithExtraBydeptCode(DateDTO dateDTO, String deptCode) {
        List<ReportBaseSalaryVO> result =baseCostMapper.listSalaryWithExtraByDeptCode(dateDTO, deptCode);
        return result;
    }

    /**
     * 人员经费二级明细
     * 传入时间+父级科室+子科室
     * 根据成本项目分组计算每个员工，各个成本项目的人员经费明细
     *
     * @param dateDTO
     * @param pDeptCode
     * @param deptCode
     * @return
     */
    @Override
    public List<ReportSalaryDetailVO> listSalaryDetailByDateAndPDeptAndDept(DateDTO dateDTO, String pDeptCode, String deptCode) {
        List<ReportSalaryDetailVO> list = new ArrayList<>();
        // 获取成本项目-人员经费详情
        List<ReportSalaryDetailVO> salaryDetailVOList = baseSalaryMapper.listSalaryDetailByDateAndPDeptAndDept(dateDTO, pDeptCode, deptCode);
        List<String> empList = salaryDetailVOList.stream().map(ReportSalaryDetailVO::getEmpId).distinct().collect(Collectors.toList());
        try {
            empList.forEach(empId ->{
                ReportSalaryDetailVO empSalary = salaryDetailVOList.stream().filter(t -> empId.equals(t.getEmpId())).findFirst().orElse(null);
                ReportSalaryDetailVO reportSalaryDetailVO = new ReportSalaryDetailVO();
                reportSalaryDetailVO.setEmpId(empId);
                reportSalaryDetailVO.setEmpName(empSalary.getEmpName());
                reportSalaryDetailVO.setDeptCode(empSalary.getDeptCode());
                reportSalaryDetailVO.setDeptName(empSalary.getDeptName());
                List<ReportSalaryDetailVO> empSalaryList = salaryDetailVOList.stream().filter(t -> empId.equals(t.getEmpId())).collect(Collectors.toList());
                Map<String,BigDecimal> map = new HashMap<>();
                BigDecimal decimal = new BigDecimal(0);
                for (ReportSalaryDetailVO vo : empSalaryList){
                    decimal = decimal.add(vo.getAmount());
                    map.put(vo.getCostItemCode(),vo.getAmount());
                }
                map.put("grhj",decimal);
                reportSalaryDetailVO.setAccParam(map);
                list.add(reportSalaryDetailVO);
            });
        }catch (Exception e){
            e.getMessage();
        }
        return list;
    }

    /**
     * 人员经费 绩效 二级明细
     * 传入时间+父级科室+子科室
     * @param dateDTO
     * @param pDeptCode
     * @param deptCode
     * @return
     */
    @Override
    public List<ReportBaseSalaryVO> listPerformanceDetailByDateAndPDeptAndDept(DateDTO dateDTO, String pDeptCode, String deptCode) {
        List<ReportBaseSalaryVO> list = baseCostMapper.listPerformanceDetailByDateAndPDeptAndDept(dateDTO,pDeptCode,deptCode);
        return list;
    }
}
